<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
    <meta name="referrer" content="never">
    <title>对象的属性描述符</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
    </style>
</head>
<body>
    
    <script type="text/javascript">
        /* 
        描述对象的属性的属性 --- 对象的属性描述符
            数据属性
                [[configuable]]  控制当前属性能否被删除，其它特性能否被修改(writable 从 true - false 除外)
                [[enumerable]]   控制当前属性能否循环（遍历/穷举/枚举）出来
                [[writable]]     控制当前属性值能否被修改
                [[value]]        当前属性对应值存储的位置
            对于直接添加在对象上的属性而言，前三个属性特性值均为 true
            使用 Object.define... 设置的属性而言，前三个属性特性默认为 false
            访问器属性

            封锁对象：
                Object.preventExtensions(obj)  阻止对象扩展属性
                Object.seal(obj)    阻止对象扩展属性，阻止对象删除属性
                Object.freeze(obj)  阻止对象扩展/删除属性，阻止对象更改已有属性           
                Object.isExtensible(obj)  判断是否阻止扩展，能扩展 true 阻止了false
                Object.isSealed(obj)  是否 seal
                Object.isFrozen(obj)  是否 freeze

        Object.getOwnpropertyDescriptor(obj, "属性名") 查看对象的属性描述符，默认获取数据属性，如果属性设置的是访问器属性，获取的就是访问器属性
        Object.definedProperty(对象, "属性名", {
            对象属性描述符
        }) 
        Object.definedProperties(对象, {
            "属性名": { 对象属性描述符 },
            "属性名": { 对象属性描述符 },
            ...
        }) 
        */

        var user = {
            name: "李白",
            age: 24
        }

        console.log("name 属性描述符", Object.getOwnPropertyDescriptor(user, "name"));

        Object.defineProperty(user, "name", {
            enumerable: false
        })

        Object.defineProperty(user, "tel", {
            value: "123435"
        })

        // Object.defineProperty(user, "tel", {
        //     writable: true
        // })

        console.log("tel 属性描述符", Object.getOwnPropertyDescriptor(user, "tel"));

        user.tel = "13567674389";
        console.log("user.tel", user.tel);

        console.log("删除成功了吗？", delete user.tel);
        
        for(var i in user){
            console.log(`属性名：${i}，属性值：${user[i]}`);
        }

        console.log(user);

        console.clear();

        var obj = {
            listen: "听",
            run(){
                console.log("running");
            }
        }

        Object.preventExtensions(obj);  // 禁止添加
        // Object.seal(obj);  // 不能添加，不能删除
        // Object.freeze(obj); // 不能添/删/改
        obj.age = 23;
        obj.listen = "music";
        delete obj.run;

        console.log(obj);
        console.log(Object.isExtensible(obj));

    </script>
</body>
</html>